package repository

import (
	"errors"
	"gorm.io/gorm"
	"lib/structs/lms"
	"lib/structs/tables"
	"lms/global"
)

var CourseDB = new(courseDB)

type courseDB struct {
}

// CheckCourseMapUser 检查是否存在课程和用户的映射
func (r courseDB) CheckCourseMapUser(userId int64, courseId int64) (b bool, err error) {
	var num int64
	err = global.DB.Model(&tables.MapCourse2User{}).Where(&tables.MapCourse2User{
		CourseId: courseId,
		UserId:   userId,
	}).Count(&num).Error
	return num > 0, err
}

// CheckCourseMapOrg 检查是否存在课程和部门的映射
func (r courseDB) CheckCourseMapOrg(orgId int64, courseId int64) (b bool, err error) {
	var num int64
	err = global.DB.Model(&tables.MapCourse2Org{}).Where(&tables.MapCourse2Org{
		CourseId: courseId,
		OrgId:    orgId,
	}).Count(&num).Error
	return num > 0, err
}

// FindUserCourse 查询用户课程
func (r courseDB) FindUserCourse(userIds []int64) (li []tables.Course, err error) {
	err = global.DB.Model(&tables.Course{}).Where(" id in (select course_id from lms_map_course_user where user_id in ? ) ", userIds).Find(&li).Error
	return
}

// FindOrgCourse 查询部门课程
func (r courseDB) FindOrgCourse(orgIds []int64) (li []tables.Course, err error) {
	err = global.DB.Model(&tables.Course{}).Where(" id in (select course_id from lms_map_course_org where org_id in ? ) ", orgIds).Find(&li).Error
	return
}

// FindPublicCourse 查询全部公开的课程
func (r courseDB) FindPublicCourse() (li []tables.Course, err error) {
	err = global.DB.Model(&tables.Course{}).Where(&tables.Course{IsPublic: true}).Find(&li).Error
	return
}

// UpdateMapCourseware 更新课件映射，删除就映射，写入新映射
func (r courseDB) UpdateMapCourseware(in lms.BindCourseware) (err error) {
	err = global.DB.Transaction(func(tx *gorm.DB) error {
		err = tx.Where(tables.MapCourseware{CourseId: in.CourseId}).Delete(&tables.MapCourseware{}).Error
		if err != nil {
			return err
		}
		var li = make([]tables.MapCourseware, len(in.CoursewareIds))
		for i := range in.CoursewareIds {
			li[i] = tables.MapCourseware{
				CourseId:     in.CourseId,
				CoursewareId: in.CoursewareIds[i],
			}
		}
		err = tx.CreateInBatches(&li, len(li)).Error
		if err != nil {
			return err
		}
		return nil
	})
	return err
}

func (r courseDB) FindCourseFolderByName(name string, parentId int64) (bool, error) {
	var m = new(tables.CourseFolder)
	err := global.DB.Where(&tables.CourseFolder{ParentId: parentId, Name: name}).First(&m).Error
	if errors.Is(gorm.ErrRecordNotFound, err) {
		return false, nil
	}
	return true, nil
}

func (r courseDB) CreateCourseFolder(m *tables.CourseFolder) (err error) {
	err = global.DB.Save(m).Error
	return
}

// DeleteFolderById 删除课程目录
func (r courseDB) DeleteFolderById(folderId int64) (err error) {
	err = global.DB.Model(&tables.CourseFolder{}).Delete(&tables.CourseFolder{FolderId: folderId}).Error
	return
}

// CountCourseNumByFolderId 统计目录下还有课程
func (r courseDB) CountCourseNumByFolderId(folderId int64) (num int64, err error) {
	err = global.DB.Raw("select count(id) from lms_course where folder_id = ? and  deleted_at =0", folderId).Scan(&num).Error
	return
}

func (r courseDB) FindFolderList() (li []tables.CourseFolder, err error) {
	err = global.DB.Find(&li).Error
	return
}

func (r courseDB) FindPage(in lms.SearchCourse) (li []tables.Course, total int64, err error) {
	err = global.DB.Model(&tables.Course{}).Where(&tables.Course{FolderId: in.FolderId, Name: in.Name}).
		Count(&total).Offset((in.PageNum - 1) * in.PageSize).Limit(in.PageSize).Find(&li).Error
	return
}

// FindCourseByName 检查同级目录下是否存在同名的课程，false-不存在
func (r courseDB) FindCourseByName(name string, folderId int64) (bool, error) {
	var m = new(tables.Course)
	err := global.DB.Where(&tables.Course{FolderId: folderId, Name: name}).First(&m).Error
	if errors.Is(gorm.ErrRecordNotFound, err) {
		return false, nil
	}
	return true, nil
}

func (r courseDB) CreateCourse(m *tables.Course, li []tables.MapCourseware) error {
	tx := global.DB.Begin()
	err := tx.Create(m).Error
	if err != nil {
		return err
	}
	if len(li) > 0 {
		err = tx.CreateInBatches(li, len(li)).Error
		if err != nil {
			return err
		}
	}
	err = tx.Commit().Error
	if err != nil {
		tx.Rollback()
		return err
	}
	return nil
}

func (r courseDB) CreateCourseMap(li []tables.MapCourseware) error {
	err := global.DB.CreateInBatches(li, len(li)).Error
	return err
}

func (r courseDB) Save(m *tables.Course) error {
	err := global.DB.Save(m).Error
	return err
}

func (r courseDB) FindById(id int64) (*tables.Course, error) {
	var m = new(tables.Course)
	err := global.DB.Where(&tables.Course{Id: id}).Find(&m).Error
	return m, err
}
